home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / util / dtype / cdt_39_10.lha / cdt / source / RCS / dispatch.c,v < prev    next >
Text File  |  1995-06-04  |  20KB  |  792 lines

  1. head    39.7;
  2. access;
  3. symbols
  4.     V39_10:39.7
  5.     c3910:39.7
  6.     V39_9:39.6;
  7. locks; strict;
  8. comment    @** @;
  9.  
  10.  
  11. 39.7
  12. date    95.06.04.16.47.28;    author StRuppert;    state Exp;
  13. branches;
  14. next    39.6;
  15.  
  16. 39.6
  17. date    95.05.10.15.00.37;    author StRuppert;    state Exp;
  18. branches;
  19. next    ;
  20.  
  21.  
  22. desc
  23. @initial
  24. @
  25.  
  26.  
  27. 39.7
  28. log
  29. @initialization for tabs buffer
  30. @
  31. text
  32. @/*
  33. ** $PROJECT: c.datatype
  34. **
  35. ** $VER: dispatch.c 39.7 (04.06.95)
  36. **
  37. ** by
  38. **
  39. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  40. **
  41. ** (C) Copyright 1995
  42. ** All Rights Reserved !
  43. **
  44. ** $HISTORY:
  45. **
  46. ** 04.06.95 : 039.007 : initialization for tabs buffer
  47. ** 10.05.95 : 039.006 : added userdefined types
  48. ** 14.04.95 : 039.005 : added inlined args support and template
  49. ** 01.04.95 : 039.004 : added GLOBAL template
  50. ** 23.03.95 : 039.003 : added TEXT arg, now full tabs handling
  51. ** 13.03.95 : 039.002 : autodoc completed
  52. ** 06.03.95 : 039.001 : initial
  53. */
  54.  
  55. /* ------------------------------- include -------------------------------- */
  56.  
  57. #include "classbase.h"
  58.  
  59. /* ------------------------------- autodoc -------------------------------- */
  60.  
  61. /*FS*/ /*"AutoDoc"*/
  62.  
  63. /*GB*** c.datatype/c.datatype ************************************************
  64.  
  65.      NAME
  66.           c.datatype - data type for any c source
  67.  
  68.      FUNCTION
  69.           This datatype is designed to display C and C++ source codes. It
  70.           display's different parts of the C source in different style and
  71.           color.At the moment these parts are :
  72.               STANDARD - any text which, doesn't match the following parts
  73.               COMMENT  - any comment such like \* ... *\ and // ...
  74.               CPP      - any C-PreProcessor keyword like "#define" or "#include"
  75.               KEYWORD  - any C/C++ keyword, which isn't handled explicitly
  76.               STORAGE  - extern,static,register,auto keywords
  77.               TYPES    - basic type keywords like int,char,long etc.
  78.               TYPENAME - any name following a struct,union,class or enum
  79.               STRING   - any string or char literal
  80.               NUMBER   - any number constant decimal,hex
  81.  
  82.           It uses a parser generated by bison with my yacc grammer.Because it's
  83.           a parser, it may occur a parse error on some unusual source code. If
  84.           this happens please send me a description of this parse error and
  85.           maybe the input file. So I can fix this problem !
  86.  
  87.      PREFS
  88.           The c.prefs file is searched first in PROGDIR:Prefs/DataTypes/ and
  89.           then in Env:DataTypes/ with the following three ReadArgs() templates :
  90.  
  91.           - CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,ITALIC/S,BOLD/S,
  92.              UNDERLINED/S,TEXT/S
  93.  
  94.              CPART is one of the explaned cpart names like COMMENT or CPP.
  95.              PEN assigns the color with the pen number to the specified part
  96.              R,G,B defines a new color for the specified part. This color is
  97.                      allocated with ObtainBestPenA(...,OBP_Precision,
  98.                                                                   PRECISION_ICON);
  99.              ITALIC,BOLD,UNDERLINED specifies the font style for the part
  100.              TEXT treat this CPART as normal text
  101.  
  102.           - GLOBAL/A/S,TABLENGTH/N/K,NONESTEDCOMMENTS/S
  103.  
  104.              GLOBAL indicates, that this line is a global setting. Note: The
  105.                   /A/S combination isn't supported from ReadArgs(), so I check
  106.                   it manually !
  107.              TABLENGTH - number of spaces to use for a tab !
  108.              NONESTEDCOMMENTS - disables nested comments
  109.  
  110.           - INLINEARGS/A/S,KEYWORD/K/A,PATTERN/K/A,LINES/N/K
  111.  
  112.              INLINEARGS indicates ,that this line is a inline args setting
  113.              KEYWORD defines the keyword to search for the inlined arguments for
  114.                   the first lines. You can specify any string, which is compared
  115.                   using strcmp(). After the keyword follows directly the pattern
  116.                   specified by PATTERN.
  117.              PATTERN defines the pattern to get the inlined arguments. Any char
  118.                   in the pattern must match the char in the text after the
  119.                   keyword. To get any arguments you can specify a template using
  120.                   the '%' char like in scanf() function. Following options are
  121.                   supported :
  122.                         %t - stands for the TABLENGTH
  123.                         %c - stands for NESTEDCOMMENTS or NONESTEDCOMMENTS
  124.              LINES - specifies the number of lines from the beginning scanned
  125.                   for inline arguments. Default is 10.
  126.  
  127.           - USERTYPES/A/S,TYPES/M
  128.  
  129.              USERTYPES indicates, that this line contains user defined types
  130.  
  131.              TYPES defines words to treat as basic types like int or long etc.
  132.  
  133.      AUTHOR
  134.           Stefan Ruppert
  135.           Windthorststrasse 5
  136.           65439 Floersheim am Main
  137.           Germany
  138.           EMail: ruppert@@vs3.informatik.fh-wiesbaden.de
  139.  
  140.      SEE ALSO
  141.           text.datatype
  142.  
  143. *****************************************************************************/
  144.  
  145. /*FE*/
  146.  
  147.  
  148. /*FS*/ /*"Definitions"*/
  149.  
  150. /* ------------------------------- defines -------------------------------- */
  151.  
  152. #define PUDDLE_SIZE        2048
  153. #define G(o)               ((struct Gadget *) (o))
  154.  
  155. #define BUFFER_SIZE        1024
  156. #define EOS                '\0'
  157.  
  158. /* ------------------------ preference definition ------------------------- */
  159.  
  160. const STRPTR prefstemplate[] = {
  161.   {"CPART/A/K,PEN/N/K,R=RED/N/K,G=GREEN/N/K,B=BLUE/N/K,"
  162.     "ITALIC/S,BOLD/S,UNDERLINED/S,TEXT/S"  },
  163.   {"GLOBAL/S,TABLENGTH/N/K,NONESTEDCOMMENTS/S" D(",DEBUG/S") },
  164.   {"INLINEARGS/S,KEYWORD/K/A,PATTERN/K/A,LINES/N/K"},
  165.   {"USERTYPES/S,TYPES/M"},
  166.   { NULL }};
  167.  
  168. D(extern int cdtparse_debug;)
  169.  
  170. enum
  171. {
  172.     TMPLT_CPART,
  173.     TMPLT_GLOBAL,
  174.     TMPLT_INLINEARGS,
  175.     TMPLT_USERTYPES
  176. };
  177.  
  178. enum
  179. {
  180.     CPARTARG_CSECTION,
  181.     CPARTARG_PEN,
  182.     CPARTARG_RED,
  183.     CPARTARG_GREEN,
  184.     CPARTARG_BLUE,
  185.     CPARTARG_ITALIC,
  186.     CPARTARG_BOLD,
  187.     CPARTARG_UNDERLINED,
  188.     CPARTARG_TEXT,
  189.     CPARTARG_MAX
  190. };
  191.  
  192. enum
  193. {
  194.     GLOBALARG_GLOBAL,
  195.     GLOBALARG_TABLENGTH,
  196.     GLOBALARG_NONESTEDCOMMENTS,
  197. #ifdef DEBUG
  198.     GLOBALARG_DEBUG,
  199. #endif
  200. };
  201.  
  202. enum
  203. {
  204.     INLINEARG_INLINE,
  205.     INLINEARG_KEYWORD,
  206.     INLINEARG_PATTERN,
  207.     INLINEARG_LINES
  208. };
  209.  
  210. enum
  211. {
  212.     USRTYPEARG_USERTYPE,
  213.     USRTYPEARG_TYPES,
  214. };
  215.  
  216. const STRPTR cparts[C_MAX] =
  217. {
  218.     "STANDARD",
  219.     "COMMENT",
  220.     "CPP",
  221.     "KEYWORD",
  222.     "STORAGE",
  223.     "TYPES",
  224.     "TYPENAME",
  225.     "STRING",
  226.     "NUMBER"
  227. };
  228.  
  229. const struct Style defstyle[C_MAX] =
  230. {
  231.     {1,0,FS_NORMAL             }, /* C_STANDARD */
  232.     {1,0,FSF_ITALIC            }, /* C_COMMENT */
  233.     {1,0,FSF_BOLD | FSF_ITALIC }, /* C_CPP */
  234.     {2,0,FSF_BOLD              }, /* C_KEYWORD */
  235.     {1,0,FSF_UNDERLINED        }, /* C_STORAGE */
  236.     {1,0,FSF_BOLD              }, /* C_TYPES */
  237.     {2,0,FS_NORMAL             }, /* C_TYPENAME */
  238.     {3,0,FS_NORMAL             }, /* C_STRING */
  239.     {3,0,FSF_BOLD              }  /* C_NUMBER */
  240. };
  241. /*FE*/
  242.  
  243. /* ------------------------------ init class ------------------------------ */
  244.  
  245. /*FS*/ LibCall Class *initClass(REGA6 struct ClassBase *cb)
  246. {
  247.     Class *cl;
  248.  
  249.     if((cl = MakeClass(DATATYPENAME,TEXTDTCLASS,NULL,sizeof(struct CData ),0)))
  250.     {
  251.         cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
  252.         cl->cl_UserData = (ULONG) cb;
  253.  
  254.         AddClass(cl);
  255.     }
  256.  
  257.     return(cl);
  258. }
  259. /*FE*/
  260.  
  261. /* ------------------------------ read prefs ------------------------------ */
  262.  
  263. /*FS*/ BOOL readPrefs(struct ClassBase *cb,struct CData *cd,STRPTR file)
  264. {
  265.     struct RDArgs *rdargs;
  266.     struct RDArgs *args;
  267.     BPTR fh;
  268.  
  269.     ENTERING;
  270.  
  271.     if((fh = Open(file,MODE_OLDFILE)))
  272.     {
  273.         UBYTE buf[256];
  274.         ULONG para[CPARTARG_MAX];
  275.         LONG i;
  276.  
  277.         DB(("def file %s opened\n",file));
  278.  
  279.         while(FGets(fh,buf,sizeof(buf)))
  280.         {
  281.             const STRPTR *tmplt = prefstemplate;
  282.             ULONG tmpltnr = 0;
  283.             BOOL done = FALSE;
  284.             DB(("line : %s",buf));
  285.  
  286.             /* skip comment and empty lines, to speed up parsing */
  287.             if(buf[0] == ';' || buf[0] == '\n')
  288.                 continue;
  289.  
  290.             while(*tmplt && !done)
  291.             {
  292.                 if((rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL)))
  293.                 {
  294.                     rdargs->RDA_Source.CS_Buffer   = buf;
  295.                     rdargs->RDA_Source.CS_Length   = strlen(buf);
  296.  
  297.                     for(i=0 ; i < (sizeof(para)/sizeof(LONG)) ; i++)
  298.                         para[i]=0;
  299.  
  300.                     DB(("rdargs at : %lx\n",rdargs));
  301.                     
  302.                     if((args = ReadArgs(*tmplt,(LONG *) para,rdargs)))
  303.                     {
  304.                         DB(("args at %lx\n",args));
  305.  
  306.                         switch(tmpltnr)
  307.                         {
  308.                         case TMPLT_CPART:
  309.                             for(i = C_MAX - 1; i >= 0 ; i--)
  310.                                 if(!Stricmp((STRPTR) para[CPARTARG_CSECTION],(STRPTR) cparts[i]))
  311.                                 {
  312.                                     struct Style *style = &cd->cd_CStyle[i];
  313.  
  314.                                     if(para[CPARTARG_TEXT])
  315.                                         style->Style = (UWORD) ~0;
  316.                                     else
  317.                                     {
  318.                                         if(para[CPARTARG_PEN])
  319.                                             style->FgPen = (UWORD) *((ULONG *) para[CPARTARG_PEN]);
  320.                                         else if(para[CPARTARG_RED] || para[CPARTARG_GREEN] || para[CPARTARG_BLUE])
  321.                                         {
  322.                                             struct PenNode *pen;
  323.                                             if((pen = AllocPooled(cd->cd_Pool,sizeof(struct PenNode))))
  324.                                             {
  325.                                                 pen->pn_Section = i;
  326.                                                 pen->pn_Pen     = -1;
  327.  
  328.                                                 if(para[CPARTARG_RED])
  329.                                                     pen->pn_Red   = (*((ULONG *) para[CPARTARG_RED]))   << 24;
  330.                                                 if(para[CPARTARG_GREEN])
  331.                                                     pen->pn_Green = (*((ULONG *) para[CPARTARG_GREEN])) << 24;
  332.                                                 if(para[CPARTARG_BLUE])
  333.                                                     pen->pn_Blue  = (*((ULONG *) para[CPARTARG_BLUE]))  << 24;
  334.  
  335.                                                 AddTail(&cd->cd_PenList,(struct Node *) pen);
  336.                                             }
  337.                                         }
  338.  
  339.                                         style->Style = FS_NORMAL;
  340.                                         if(para[CPARTARG_ITALIC])
  341.                                             style->Style |= FSF_ITALIC;
  342.                                         if(para[CPARTARG_BOLD])
  343.                                             style->Style |= FSF_BOLD;
  344.                                         if(para[CPARTARG_UNDERLINED])
  345.                                             style->Style |= FSF_UNDERLINED;
  346.                                     }
  347.                                 }
  348.                             done = TRUE;
  349.                             break;
  350.                         case TMPLT_GLOBAL:
  351.                             if(para[GLOBALARG_GLOBAL])
  352.                             {
  353.                                 if(para[GLOBALARG_TABLENGTH])
  354.                                     cd->cd_TabLength = *((ULONG *) para[GLOBALARG_TABLENGTH]);
  355.  
  356.                                 if(para[GLOBALARG_NONESTEDCOMMENTS])
  357.                                     cd->cd_Flags.Nested = FALSE;
  358.  
  359.                                 D({
  360.                                     if(para[GLOBALARG_DEBUG])
  361.                                         cdtparse_debug = 1;
  362.                                     bug("yydebug is : %ld\n",cdtparse_debug);
  363.                                   });
  364.                                 done = TRUE;
  365.                             }
  366.                             break;
  367.                         case TMPLT_INLINEARGS:
  368.                             if(para[INLINEARG_INLINE])
  369.                             {
  370.                                 cd->cd_Flags.Inline = TRUE;
  371.  
  372.                                 if(para[INLINEARG_LINES])
  373.                                     cd->cd_Inline.Lines = *((ULONG *) para[INLINEARG_LINES]);
  374.  
  375.                                 strncpy(cd->cd_Inline.Keyword,(STRPTR) para[INLINEARG_KEYWORD],INLINE_BUFFER);
  376.                                 cd->cd_Inline.Keyword[INLINE_BUFFER-1] = EOS;
  377.  
  378.                                 strncpy(cd->cd_Inline.Pattern,(STRPTR) para[INLINEARG_PATTERN],INLINE_BUFFER);
  379.                                 cd->cd_Inline.Pattern[INLINE_BUFFER-1] = EOS;
  380.                                 done = TRUE;
  381.                             }
  382.                             break;
  383.                         case TMPLT_USERTYPES:
  384.                             if(para[USRTYPEARG_USERTYPE] && para[USRTYPEARG_TYPES])
  385.                             {
  386.                                 struct Node *node;
  387.                                 STRPTR *types = (STRPTR *) para[USRTYPEARG_TYPES];
  388.  
  389.                                 while(*types)
  390.                                 {
  391.                                     DB(("usertype : %s\n",*types));
  392.                                     if((node = AllocPooled(cd->cd_Pool,sizeof(struct Node) + strlen(*types) + 1)))
  393.                                     {
  394.                                         node->ln_Name = (STRPTR) (node + 1);
  395.                                         strcpy(node->ln_Name,*types);
  396.                                         node->ln_Type = strlen(node->ln_Name);
  397.                                         AddTail(&cd->cd_UserTypes,node);
  398.                                     }
  399.                                     types++;
  400.                                 }
  401.                                 done = TRUE;
  402.                             }
  403.                             break;
  404.                         }
  405.                     }
  406.  
  407.                     FreeDosObject(DOS_RDARGS , rdargs);
  408.                 }
  409.                 tmpltnr++;
  410.                 tmplt++;
  411.             }
  412.         }
  413.         Close(fh);
  414.     }
  415.  
  416.     LEAVING;
  417.  
  418.     return((BOOL) (fh == NULL));
  419. }
  420. /*FE*/
  421.  
  422. /* ---------------------------- notify object ----------------------------- */
  423.  
  424. /*FS*/ ULONG notifyAttrChanges(Object * o, void * ginfo, ULONG flags, ULONG tag1,...)
  425. {
  426.      return(DoMethod(o, OM_NOTIFY, &tag1, ginfo, flags));
  427. }
  428. /*FE*/
  429.  
  430. /* --------------------------- class dispatcher --------------------------- */
  431.  
  432. /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
  433. {
  434.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  435.     struct CData *cd = INST_DATA(cl,obj);
  436.     ULONG retval;
  437.  
  438.     switch(msg->MethodID)
  439.     {
  440.     case OM_NEW:
  441.         {
  442.             Object *newobj;
  443.             if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
  444.             {
  445.                 cd = INST_DATA(cl,newobj);
  446.  
  447.                 NewList(&cd->cd_PenList);
  448.                 NewList(&cd->cd_UserTypes);
  449.  
  450.                 cd->cd_TabLength = 8;
  451.  
  452.                 cd->cd_Flags.Nested = TRUE;
  453.                 cd->cd_Inline.Lines = 10;
  454.  
  455.                 if((cd->cd_Pool = CreatePool(MEMF_CLEAR | MEMF_ANY , PUDDLE_SIZE,PUDDLE_SIZE)))
  456.                 {
  457.                     STRPTR buffer = NULL;
  458.                     ULONG bufferlen = 0;
  459.  
  460.                     if(GetDTAttrs(newobj,TDTA_Buffer    ,&buffer,
  461.                                                 TDTA_BufferLen ,&bufferlen,
  462.                                                 TAG_DONE) == 2 && buffer && bufferlen)
  463.                     {
  464.                         int i;
  465.  
  466.                         for(i = 0 ; i < C_MAX ; i++)
  467.                             cd->cd_CStyle[i] = defstyle[i];
  468.  
  469.                         for(i = 0 ; i < sizeof(cd->cd_TabBuffer) ; i++)
  470.                             cd->cd_TabBuffer[i] = ' ';
  471.  
  472.                         if(readPrefs(cb,cd,"PROGDIR:Prefs/DataTypes/c.prefs"))
  473.                             readPrefs(cb,cd,"Env:DataTypes/c.prefs");
  474.  
  475.                         if(cd->cd_Flags.Inline)
  476.                         {
  477.                             STRPTR ptr = buffer;
  478.                             STRPTR end = buffer + bufferlen;
  479.                             STRPTR pat = cd->cd_Inline.Pattern;
  480.                             ULONG lines = cd->cd_Inline.Lines;
  481.                             ULONG kwlen = strlen(cd->cd_Inline.Keyword);
  482.  
  483.                             while(lines > 0 && ptr < end)
  484.                             {
  485.                                 if(*ptr == '\n')
  486.                                     lines--;
  487.                                 else if(*ptr == cd->cd_Inline.Keyword[0] &&
  488.                                           !strncmp(cd->cd_Inline.Keyword,ptr,kwlen))
  489.                                 {
  490.                                     ptr += kwlen;
  491.                                     do
  492.                                     {
  493.                                         if(*pat == '%')
  494.                                         {
  495.                                             pat++;
  496.                                             switch(*pat)
  497.                                             {
  498.                                             case 't':
  499.                                                 {
  500.                                                     LONG num,value;
  501.                                                     if((num = StrToLong(ptr,&value)) > 0)
  502.                                                     {
  503.                                                         cd->cd_TabLength = value;
  504.                                                         ptr += num;
  505.                                                     }
  506.                                                 }
  507.                                                 break;
  508.                                             case 'c':
  509.                                                 if(!Strnicmp(ptr,"NESTEDCOMMENTS",14))
  510.                                                 {
  511.                                                     ptr += 14;
  512.                                                     cd->cd_Flags.Nested = TRUE;
  513.                                                 } else if(!Strnicmp(ptr,"NONESTEDCOMMENTS",16))
  514.                                                 {
  515.                                                     ptr +=16;
  516.                                                     cd->cd_Flags.Nested = FALSE;
  517.                                                 }
  518.                                                 break;
  519.                                             }
  520.                                             pat++;
  521.                                         }
  522.                                     } while(*ptr !='\n' && *ptr++ == *pat++);
  523.                                     break;
  524.                                 }
  525.                                 ptr++;
  526.                             }
  527.                         }
  528.  
  529.                         retval = (ULONG) newobj;
  530.                     } else
  531.                         SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  532.                 }
  533.             }
  534.  
  535.             if(!retval)
  536.             {
  537.                 D(bug("c.datatype error : %ld\n",IoErr()));
  538.                 CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
  539.             }
  540.         }
  541.         break;
  542.     case OM_DISPOSE:
  543.         {
  544.             struct List *linelist;
  545.             struct PenNode *pen;
  546.  
  547.             if(GetDTAttrs(obj,TDTA_LineList,&linelist,TAG_DONE) && linelist)
  548.                 NewList(linelist);
  549.  
  550.             while((pen = (struct PenNode *) RemHead(&cd->cd_PenList)))
  551.                 if(pen->pn_Pen != -1)
  552.                     ReleasePen(cd->cd_ColorMap,pen->pn_Pen);
  553.  
  554.             if(cd->cd_Pool)
  555.                 DeletePool(cd->cd_Pool);
  556.  
  557.             retval = DoSuperMethodA(cl,obj,msg);
  558.         }
  559.         break;
  560.     case OM_SET:
  561.     case OM_UPDATE:
  562.         /* Pass the attributes to the super class and force a refresh
  563.          * if we need it */
  564.         if((retval = DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
  565.         {
  566.             struct RastPort *rp;
  567.  
  568.             /* Get a pointer to the rastport */
  569.             if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
  570.             {
  571.                 struct gpRender gpr;
  572.  
  573.                 /* Force a redraw */
  574.                 gpr.MethodID   = GM_RENDER;
  575.                 gpr.gpr_GInfo  = ((struct opSet *) msg)->ops_GInfo;
  576.                 gpr.gpr_RPort  = rp;
  577.                 gpr.gpr_Redraw = GREDRAW_UPDATE;
  578.                 DoMethodA (obj, (Msg) &gpr);
  579.  
  580.                 /* Release the temporary rastport */
  581.                 ReleaseGIRPort (rp);
  582.             }
  583.         }
  584.         break;
  585.     case GM_LAYOUT:
  586.          /* Tell everyone that we are busy doing things */
  587.          notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
  588.                                   GA_ID,       G(obj)->GadgetID,
  589.                                   DTA_Busy,    TRUE,
  590.                                   TAG_DONE);
  591.         /* Let the super-class partake */
  592.         retval = DoSuperMethodA (cl, obj, msg);
  593.  
  594.         /* We need to do this one asynchronously */
  595.         retval += DoAsyncLayout (obj, (struct gpLayout *) msg);
  596.         break;
  597.     case DTM_PROCLAYOUT:
  598.         /* Tell everyone that we are busy doing things */
  599.         notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
  600.                                  GA_ID,       G(obj)->GadgetID,
  601.                                  DTA_Busy,    TRUE,
  602.                                  TAG_DONE);
  603.  
  604.         /* Let the super-class partake and then fall through to our layout method */
  605.         DoSuperMethodA (cl, obj, msg);
  606.     case DTM_ASYNCLAYOUT:
  607.         /* Layout the text */
  608.         retval = layout(cb, cl, obj, (struct gpLayout *) msg);
  609.         break;
  610.     default:
  611.         retval = DoSuperMethodA(cl,obj,msg);
  612.     }
  613.  
  614.     return(retval);
  615. }
  616. /*FE*/
  617.  
  618. /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
  619. {
  620.     struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
  621.     struct CData *cd = INST_DATA(cl,obj);
  622.  
  623.     struct CParse cparse;
  624.     struct RastPort trp;
  625.  
  626.     ULONG visible;
  627.     ULONG hunit;
  628.  
  629.     ULONG total = 0;
  630.     ULONG bsig = 0;
  631.  
  632.     /* Attributes obtained from super-class */
  633.     struct TextAttr *tattr;
  634.     struct TextFont *font;
  635.     struct List *linelist;
  636.     ULONG bufferlen;
  637.     STRPTR buffer;
  638.  
  639.     struct IBox *domain;
  640.     STRPTR title;
  641.  
  642.     D(bug("layout !\n"));
  643.  
  644.     /* Get all the attributes that we are going to need for a successful layout */
  645.     if(GetDTAttrs(obj,DTA_TextFont,  (ULONG) &font,
  646.                             DTA_TextAttr,  (ULONG) &tattr,
  647.                             DTA_Domain,    (ULONG) &domain,
  648.                             DTA_ObjName,   (ULONG) &title,
  649.                             TDTA_LineList, (ULONG) &linelist,
  650.                             TDTA_Buffer,   (ULONG) &buffer,
  651.                             TDTA_BufferLen,(ULONG) &bufferlen,
  652.                             TAG_DONE) == 7)
  653.     {
  654.         ULONG maxwidth = 0;
  655.  
  656.         /* Lock the global object data so that nobody else can manipulate it */
  657.         ObtainSemaphore (&(si->si_Lock));
  658.  
  659.         /* Make sure we have a buffer */
  660.         if(buffer)
  661.         {
  662.             /* Initialize the temporary RastPort */
  663.             InitRastPort (&trp);
  664.             SetFont (&trp, font);
  665.  
  666.             /* We only need to perform layout if we are doing word wrap, or this
  667.              * is the initial layout call */
  668.             if (gpl->gpl_Initial)
  669.             {
  670.                 struct PenNode *pen;
  671.  
  672.                 if((cd->cd_ColorMap = gpl->gpl_GInfo->gi_Screen->ViewPort.ColorMap))
  673.                 {
  674.                     for(pen = (struct PenNode *) cd->cd_PenList.lh_Head ;
  675.                          pen->pn_Node.mln_Succ ;
  676.                          pen = (struct PenNode *) pen->pn_Node.mln_Succ)
  677.                     {
  678.                         pen->pn_Pen = ObtainBestPen(cd->cd_ColorMap,
  679.                                                              pen->pn_Red,pen->pn_Green,pen->pn_Blue,
  680.                                                              OBP_Precision , PRECISION_ICON,
  681.                                                              TAG_DONE);
  682.                         DB(("pen : %ld allocated for section %ld with RGB : %lx %lx %lx\n",
  683.                              pen->pn_Pen,pen->pn_Section,pen->pn_Red,pen->pn_Green,pen->pn_Blue));
  684.  
  685.                         if(pen->pn_Pen > 0)
  686.                             cd->cd_CStyle[pen->pn_Section].FgPen = pen->pn_Pen;
  687.                         else
  688.                             cd->cd_CStyle[pen->pn_Section].FgPen = 1;
  689.                     }
  690.                 }
  691.  
  692.                 cparse.BegPtr   = buffer;
  693.                 cparse.ActPtr   = buffer;
  694.                 cparse.TxtPtr   = buffer;
  695.                 cparse.SegPtr   = buffer;
  696.                 cparse.EndPtr   = buffer + bufferlen;
  697.                 cparse.TabWidth = TextLength(&trp," ",1);
  698.                 cparse.Mode     = C_STANDARD;
  699.  
  700.                 cparse.XOffset  = 0;
  701.                 cparse.YOffset  = 0;
  702.                 cparse.MaxWidth = 0;
  703.  
  704.                 cparse.LineList = linelist;
  705.                 cparse.RPort    = &trp;
  706.                 cparse.Data     = cd;
  707.  
  708.                 D({ BPTR fh;
  709.                      BPTR oldfh;
  710.                      if(cdtparse_debug)
  711.                      if((fh = Open("CON:////C-DataType YYDebug/WAIT/CLOSE",MODE_NEWFILE)))
  712.                          oldfh = SelectOutput(fh);
  713.                  );
  714.  
  715.                 cdtparse_parse(cb,&cparse);
  716.  
  717.                 cdtparse_free(cb,&cparse);
  718.  
  719.                 D(  if(fh && cdtparse_debug)
  720.                      {
  721.                         SelectOutput(oldfh);
  722.                         Close(fh);
  723.                      }
  724.                   }
  725.                  );
  726.  
  727.                 total    = cparse.YOffset / font->tf_YSize;
  728.                 maxwidth = cparse.MaxWidth;
  729.             }
  730.             else
  731.             {
  732.                 /* No layout to perform */
  733.                 total    = si->si_TotVert;
  734.                 maxwidth = si->si_TotHoriz;
  735.             }
  736.         }
  737.  
  738.         /* Compute the lines and columns type information */
  739.         si->si_VertUnit  = font->tf_YSize;
  740.         si->si_VisVert   = visible = domain->Height / si->si_VertUnit;
  741.         si->si_TotVert   = total;
  742.  
  743.         si->si_HorizUnit = hunit = font->tf_XSize;
  744.         si->si_VisHoriz  = (LONG) domain->Width / hunit;
  745.         si->si_TotHoriz  = maxwidth / hunit;
  746.  
  747.         /* Release the global data lock */
  748.         ReleaseSemaphore(&si->si_Lock);
  749.  
  750.         /* Were we aborted? */
  751.         if (bsig == 0)
  752.         {
  753.             /* Not aborted, so tell the world of our newest attributes */
  754.             notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
  755.                                      GA_ID,                   G(obj)->GadgetID,
  756.  
  757.                                      DTA_VisibleVert,         visible,
  758.                                      DTA_TotalVert,           total,
  759.                                      DTA_NominalVert,         font->tf_YSize * 25,
  760.                                      DTA_VertUnit,            font->tf_YSize,
  761.  
  762.                                      DTA_VisibleHoriz,        (ULONG) (domain->Width / hunit),
  763.                                      DTA_TotalHoriz,          maxwidth / hunit,
  764.                                      DTA_NominalHoriz,        font->tf_XSize * 80,
  765.                                      DTA_HorizUnit,           hunit,
  766.  
  767.                                      DTA_Title,               title,
  768.                                      DTA_Busy,                FALSE,
  769.                                      DTA_Sync,                TRUE,
  770.                                      TAG_DONE);
  771.         }
  772.     }
  773.  
  774.     return(total);
  775. }
  776. /*FE*/
  777.  
  778. @
  779.  
  780.  
  781. 39.6
  782. log
  783. @*** empty log    message    ***
  784. @
  785. text
  786. @d4 1
  787. a4 1
  788. ** $VER: dispatch.c 39.6 (10.05.95)
  789. d15 1
  790. d437 3
  791. @
  792.